﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.IO;

namespace StartupTaskRunner.Logging
{
    /// <summary>
    /// Class for logging messages to a configured log listener.
    /// </summary>
    public static class Logger
    {
        private static string _filename;
        private static TraceListener _traceListener;
        /// <summary>
        /// Static constructor for initializing the logger
        /// </summary>
        static Logger()
        {
            _traceListener = new TextWriterTraceListener(GetLogFilename());
            Trace.Listeners.Add(_traceListener);
            Trace.AutoFlush = true;
        }

        /// <summary>
        /// Gets the filename of the logfile.
        /// </summary>
        /// <returns></returns>
        public static string GetLogFilename()
        {
            if (string.IsNullOrWhiteSpace(_filename))
            {
                string appName = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
                string now = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss");
                if (RoleEnvironment.IsAvailable)
                {
                    _filename = string.Format("{0}_{1}_{2}_{3}.log", now, appName, RoleEnvironment.CurrentRoleInstance.Role.Name, RoleEnvironment.CurrentRoleInstance.Id);
                }
                else
                {
                    _filename = string.Format("{0}_{1}.log",now, appName);
                }
            }

            return _filename;
        }

        /// <summary>
        /// Logs a messages to the configured sources
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public static void WriteMessage(string message, params object[] args)
        {
            WriteTimeStampedMessage(message, args);
        }

        private static void WriteTimeStampedMessage(string message, params object[] args)
        {
            string completeMessage = String.Format(message, args);
            string dateTime = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");
            completeMessage = String.Format("{0} : {1}", dateTime, completeMessage);

            Trace.WriteLine(completeMessage);
        }

        private static void WriteSimpleMessage(string message, params object[] args)
        {
            Trace.WriteLine(String.Format(message, args));
        }

        /// <summary>
        /// Logs an exception to the configured sources
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public static void LogException(Exception ex)
        {
            WriteException(ex);
        }

        /// <summary>
        /// Logs an exception to the configured sources
        /// </summary>
        /// <param name="message"></param>
        /// <param name="args"></param>
        public static void LogException(Exception ex, string message, params object[] args)
        {
            WriteTimeStampedMessage(message, args);
            WriteException(ex);
        }

        private static void WriteException(Exception ex)
        {
            WriteSimpleMessage("Message: {0}", ex.Message);
            WriteSimpleMessage("Source: {0}", ex.Source);
            WriteSimpleMessage("StackTrace: {0}", ex.StackTrace);
            WriteSimpleMessage("TargetSite: {0}", ex.TargetSite);
            if (ex.InnerException != null)
            {
                WriteException(ex.InnerException);
            }
        }

        /// <summary>
        /// CLoses the logfile for copy
        /// </summary>
        public static void Close()
        {
            if (Trace.Listeners.Contains(_traceListener))
            {
                Trace.Listeners.Remove(_traceListener);
                
            }
            _traceListener.Close();
        }
    }
}
